#include "stdafx.h"
#include "CpUtil.h"

using namespace CppClean;
//////////////////////////////////////////////////////////////////////////
//CDbgUtil
//////////////////////////////////////////////////////////////////////////
void CDbgUtil::myDebugOutputW(LPCWSTR format, BOOL bNewLine, ...)
{
	va_list argptr;
	va_start(argptr, bNewLine);
	TCHAR szData[MAX_STRING_LEN] = {0};
	_vsntprintf(szData, MAX_STRING_LEN - 1, format, argptr);
	va_end(argptr);
	if(bNewLine)
		_tcscat(szData, _T("\r\n"));

	OutputDebugStringW(szData);
}

void CDbgUtil::myDebugOutputA(LPCSTR format, BOOL bNewLine, ...)
{
	va_list argptr;
	va_start(argptr, bNewLine);
	CHAR szData[MAX_STRING_LEN] = {0};
	_vsnprintf(szData, MAX_STRING_LEN - 1, format, argptr);
	va_end(argptr);
	if(bNewLine)
		strcat(szData, "\r\n");

	OutputDebugStringA(szData);
}

//////////////////////////////////////////////////////////////////////////
//CCharUtil
//////////////////////////////////////////////////////////////////////////
void CCharUtil::AppendSet(CHARSET& sets, const char* strings)
{
	if(strings == NULL)
		return;

	int nLen = strlen(strings);
	for(int i = 0; i < nLen; i++)
		sets.insert(strings[i]);
}

bool CCharUtil::InSet(const char ch, CHARSET& sets)
{
	CHARSET::iterator it = sets.find(ch);
	return it != sets.end();
}

void CCharUtil::DumpSet(CHARSET& sets)
{
	CHARSET::iterator it = sets.begin();
	for(; it != sets.end(); it++)
	{
		char ch = *it;
		CDbgUtil::myDebugOutputA("'%c' ", FALSE, ch);
	}
	CDbgUtil::myDebugOutputA("\r\n", FALSE);
}

int CCharUtil::findchar(const char* source, const char* str, int start)
{
	const char* ret = strstr(source + start, str);
	if(ret != NULL)
		return ret - source;

	return -1;
}

int CCharUtil::findchar(const char* source, char ch, int start)
{
	const char* ret = strchr(source + start, ch);
	if(ret != NULL)
		return ret - source;

	return -1;
}

//////////////////////////////////////////////////////////////////////////
//CStringUtil
//////////////////////////////////////////////////////////////////////////
bool CStringUtil::InSet(const char* str, STRINGSET& sets)
{
	STRINGSET::iterator it = sets.find(string(str));
	return it != sets.end();
}

void CStringUtil::DumpSet(STRINGSET& sets)
{
	STRINGSET::iterator it = sets.begin();
	for(; it != sets.end(); it++)
	{
		const string& sTemp = *it;
		CDbgUtil::myDebugOutputA("'%s' ", FALSE, sTemp.c_str());
	}
	CDbgUtil::myDebugOutputA("\r\n", FALSE);
}

//////////////////////////////////////////////////////////////////////////
//CFileUtil
//////////////////////////////////////////////////////////////////////////
CFileUtil::CFileUtil()
:m_hFile(NULL)
{
}

CFileUtil::~CFileUtil()
{
	Close();
}

bool CFileUtil::Open(LPCTSTR lpszFileName, bool bReadOnly)
{
	if(bReadOnly)
	{
		m_hFile = CreateFile(lpszFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
	}
	else
	{
		m_hFile = CreateFile(lpszFileName, GENERIC_WRITE|GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
	}
	if(m_hFile == INVALID_HANDLE_VALUE || m_hFile == NULL)
	{
		m_hFile = NULL;
		return false;
	}
	return true;		
}

void CFileUtil::Close()
{
	if(m_hFile != NULL)
	{
		FlushFileBuffers(m_hFile);
		CloseHandle(m_hFile);
	}
	m_hFile = NULL;
}

LONGLONG CFileUtil::GetFileSize()
{
	if(m_hFile == NULL)
		return -1;

	LARGE_INTEGER fileSize = {0};
	fileSize.LowPart = ::GetFileSize(m_hFile, (DWORD*)&fileSize.HighPart);

	return fileSize.QuadPart;
}

int CFileUtil::Read(LPBYTE lpData, int nSize)
{
	if(lpData == NULL || nSize == 0)
		return -1;

	DWORD dwRead = 0;
	if(!::ReadFile(m_hFile, lpData, nSize, &dwRead, NULL))
		return -1;

	return (int)dwRead;
}

int CFileUtil::Write(LPBYTE lpData, int nSize)
{
	if(lpData == NULL || nSize == 0)
		return -1;

	DWORD dwWrite = 0;
	if(!::WriteFile(m_hFile, lpData, nSize, &dwWrite, NULL))
		return -1;

	return (int)dwWrite;
}

 DWORD CFileUtil::ReadFile(LPCTSTR lpszFileName, char** ppData)
{
	if(ppData == NULL)
		return 0;

	*ppData = NULL;
	CFileUtil util;
	if(!util.Open(lpszFileName))
		return (DWORD)(-1);

	LONGLONG llFileSize = util.GetFileSize();
	char* pRet = new char[llFileSize];
	if(!pRet)
		return (DWORD)(-1);

	int nRead = util.Read((LPBYTE)pRet, llFileSize);
	if(nRead <= 0)
	{
		delete [] pRet;
		return (DWORD)(-1);
	}
	*ppData = pRet;
	return nRead;
}
